using Microsoft.AspNetCore.Identity.UI.Services;
using Identity.HttpAPI;
using BuildingBlocks;
using Identity.Application;
using Identity.Infrastructure;
using BuildingBlocks.Infrastructure.EventBus;
using Identity.Application.Contracts.Events;
using Identity.Infrastructure.EventHandlers;
using Identity.HttpAPI.Host.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using BuildingBlocks.Abstractions.Permissions;
using Identity.HttpAPI.Permission;
using Identity.HttpAPI.Controllers;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Identity.HttpAPI.GrpcServices;
using Identity.Application.Contracts.Services;
using Microsoft.IdentityModel.Tokens;



JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

var builder = WebApplication.CreateBuilder(args);


builder.Services.Configure<SmtpOptions>(builder.Configuration.GetSection("Smtp"));
builder.Services.AddTransient<IEmailSender, NullEmailSender>();

builder.Services.ConfigureApplicationCookie(options =>
{
    options.Cookie.SameSite = SameSiteMode.None;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    // 视部署还可以设置 options.Cookie.HttpOnly = true;
});

builder.Services.AddBuildingBlocksCore(builder.Configuration);
builder.Services.AddIdentityApplication();
builder.Services.AddIdentityInfrastructure(builder.Configuration);


builder.Services.AddIdentityServices(builder.Configuration);
builder.Services.AddOpenIddictServerWithClaims();

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "Bearer";
    options.DefaultChallengeScheme = "Bearer";

})
.AddJwtBearer("Bearer", options =>
{
    options.Authority = "https://localhost:7291/";
    options.Audience = "api";
    options.RequireHttpsMetadata = false;
    options.Events = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            Console.WriteLine($"JWT 验证失败: {context.Exception?.Message}");
            return Task.CompletedTask;
        },
        OnTokenValidated = context =>
        {
            Console.WriteLine($"JWT 验证成功, subject: {context.Principal?.Identity?.Name}");
            return Task.CompletedTask;
        }


    };
   

});

builder.Services.AddScoped<IAuthorizationHandler, MixedPermissionHandler>();


builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("Permission", policy =>
    {
        policy.Requirements.Add(new PermissionRequirement());
    });
});


builder.Services.ConfigureApplicationCookie(options =>
{
    // 当未认证时返回 401，而不是重定向到 /Account/Login
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
    };

    options.Events.OnRedirectToAccessDenied = context =>
    {
        context.Response.StatusCode = StatusCodes.Status403Forbidden;
        return Task.CompletedTask;
    };
});

builder.Services.AddControllers();
builder.Services.AddLogging(builder =>
{
    builder.AddConsole();
    builder.AddDebug();
    builder.SetMinimumLevel(LogLevel.Debug);
});

builder.Services.AddGrpc(); // 注册 gRPC 服务
/* builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenLocalhost(5210, listenOptions =>
    {
        listenOptions.UseHttps("localhost.pfx", "123456"); // 使用自签名证书
        listenOptions.Protocols = HttpProtocols.Http2;      // 强制 HTTP/2
    });
}); */

builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenLocalhost(7291, listenOptions =>
    {
        listenOptions.UseHttps(); // 使用默认开发证书
    });
});
builder.Services.AddSingleton<IPermissionProvider>(sp =>
    new PermissionScannerProvider(typeof(AccountController).Assembly));


var app = builder.Build();


app.UseCors("AllowLocalFrontend");


await ApplicationSeeder.SeedPublicClientAsync(app.Services);

app.UseHttpsRedirection();

app.UseRouting();



app.UseAuthentication();
app.UseAuthorization();
app.MapGrpcService<PermissionCenterGrpcService>();
app.MapGrpcService<PermissionBindingGrpcService>();

var eventBus = app.Services.GetRequiredService<IEventBus>();
eventBus.Subscribe<UserRegisteredEvent, UserRegisteredEventHandler>();
eventBus.Subscribe<SendCodeEmailWithResetPasswordEvent, SendCodeEmailWithResetPasswordEventHandler>();
eventBus.Subscribe<PermissionRegisteredEvent, PermissionRegisteredEventHandler>();

app.UseSwagger();
app.UseSwaggerUI();


app.MapControllers();


app.Run();
